﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Reflection.Metadata;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Mvvm.Helpers;
using Mvvm.Models;
using Mvvm.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Mvvm.Services;

public class ChatTimeAIAdviceService : IChatTimeAIAdviceService
{
    private readonly IAlertService _alertService = new AlertService();

    private const string Server = "生成故事服务器";

    static ClientWebSocket webSocket0;

    static CancellationToken cancellation;

    // 应用APPID（必须为webapi类型应用，并开通星火认知大模型授权）
    const string x_appid = "ab14464b";

    // 接口密钥（webapi类型应用开通星火认知大模型后，控制台--我的应用---星火认知大模型---相应服务的apikey）
    const string api_secret = "ZDI3MzlhZTU0NjY1NmFkNWRkMmU5Y2Fj";

    // 接口密钥（webapi类型应用开通星火认知大模型后，控制台--我的应用---星火认知大模型---相应服务的apisecret）
    const string api_key = "77d4018b44adc649ba1d6b70ba80788b";

    static string hostUrl = "wss://spark-api.xf-yun.com/v4.0/chat";

    public string GetChatData(List<ChatData> chatDataList)
    {
        var lastTime = chatDataList.Max(t=>t.Timestamp);
        int firstIndex = -1;
        for (int i = chatDataList.Count - 1; i >= 0; i--)
        {
            if (lastTime - chatDataList[i].Timestamp >= TimeSpan.FromDays(7))
            {
                firstIndex = i;
                break;
            }
        }

        if (chatDataList.Count - firstIndex - 1 < 10)
        {
            firstIndex = -1;
        }

        if (firstIndex != -1)
        {
            for (int i = 0; i <= firstIndex; i++)
            {
                chatDataList.RemoveAt(i);
            }
        }

        string chatData = "";
        
        for (int i = 0; i < chatDataList.Count; i++)
        {
            chatData += chatDataList[i].ToString();
        }
        return chatData;
    }

     public async Task<string> CreateChatTimeAIAdvice(Content _content)
    {
        string authUrl = GetAuthUrl();
        string url = authUrl.Replace("http://", "ws://").Replace("https://", "wss://");
        using (webSocket0 = new ClientWebSocket())
        {
            try
            {
                await webSocket0.ConnectAsync(new Uri(url), cancellation);

                JsonRequest request = new JsonRequest();
                request.header = new Header()
                {
                    app_id = x_appid,
                    uid = "12345"
                };
                request.parameter = new Parameter()
                {
                    chat = new Chat()
                    {
                        domain = "4.0Ultra", //模型领域，默认为星火通用大模型

                        temperature = 0.5, //温度采样阈值，用于控制生成内容的随机性和多样性，值越大多样性越高；范围（0，1）
                        max_tokens = 1024, //生成内容的最大长度，范围（0，4096）
                    }
                };
                request.payload = new Payload()
                {
                    message = new Message()
                    {
                        text = new List<Content>
                        {
                            _content,
                            // new Content() { role = "assistant", content = "....." },
                            // // AI的历史回答结果，这里省略了具体内容，可以根据需要添加更多历史对话信息和最新问题的内容。
                        }
                    }
                };

                string jsonString = JsonConvert.SerializeObject(request);
                //连接成功，开始发送数据


                var frameData2 = System.Text.Encoding.UTF8.GetBytes(jsonString.ToString());


                webSocket0.SendAsync(new ArraySegment<byte>(frameData2), WebSocketMessageType.Text, true, cancellation);

                // 接收流式返回结果进行解析
                byte[] receiveBuffer = new byte[1024];
                WebSocketReceiveResult result =
                    await webSocket0.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), cancellation);
                String resp = "";
                while (!result.CloseStatus.HasValue)
                {
                    if (result.MessageType == WebSocketMessageType.Text)
                    {
                        string receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, result.Count);
                        //将结果构造为json

                        JObject jsonObj = JObject.Parse(receivedMessage);
                        int code = (int)jsonObj["header"]["code"];


                        if (0 == code)
                        {
                            int status = (int)jsonObj["payload"]["choices"]["status"];


                            JArray textArray = (JArray)jsonObj["payload"]["choices"]["text"];
                            string content = (string)textArray[0]["content"];
                            resp += content;

                            if (status != 2)
                            {
                            }
                            else
                            {
                                int totalTokens = (int)jsonObj["payload"]["usage"]["text"]["total_tokens"];
                                /*Console.WriteLine($"整体返回结果： {resp}");*/
                                return resp;
                            }
                        }
                        else
                        {
                            Console.WriteLine($"请求报错： {receivedMessage}");
                        }
                    }
                    else if (result.MessageType == WebSocketMessageType.Close)
                    {
                        Console.WriteLine("已关闭WebSocket连接");
                        break;
                    }

                    result = await webSocket0.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), cancellation);
                }
            }
            catch (Exception e)
            {
                await _alertService.AlertAsync(
                    ErrorMessageHelper.HttpClientErrorTitle,
                    ErrorMessageHelper.GetHttpClientError(Server, e.Message));
                return "生成建议失败！";
            }
        }

        return null;
    }

    // 返回code为错误码时，请查询https://www.xfyun.cn/document/error-code解决方案
    static string GetAuthUrl()
    {
        string date = DateTime.UtcNow.ToString("r");

        Uri uri = new Uri(hostUrl);
        StringBuilder builder = new StringBuilder("host: ").Append(uri.Host).Append("\n"). //
            Append("date: ").Append(date).Append("\n"). //
            Append("GET ").Append(uri.LocalPath).Append(" HTTP/1.1");

        string sha = HMACsha256(api_secret, builder.ToString());
        string authorization = string.Format("api_key=\"{0}\", algorithm=\"{1}\", headers=\"{2}\", signature=\"{3}\"",
            api_key, "hmac-sha256", "host date request-line", sha);
        //System.Web.HttpUtility.UrlEncode

        string NewUrl = "https://" + uri.Host + uri.LocalPath;

        string path1 = "authorization" + "=" +
                       Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(authorization));
        date = date.Replace(" ", "%20").Replace(":", "%3A").Replace(",", "%2C");
        string path2 = "date" + "=" + date;
        string path3 = "host" + "=" + uri.Host;

        NewUrl = NewUrl + "?" + path1 + "&" + path2 + "&" + path3;
        return NewUrl;
    }


    public static string HMACsha256(string apiSecretIsKey, string buider)
    {
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(apiSecretIsKey);
        System.Security.Cryptography.HMACSHA256 hMACSHA256 = new System.Security.Cryptography.HMACSHA256(bytes);
        byte[] date = System.Text.Encoding.UTF8.GetBytes(buider);
        date = hMACSHA256.ComputeHash(date);
        hMACSHA256.Clear();

        return Convert.ToBase64String(date);
    }
}

public class JsonRequest
{
    public Header header { get; set; }
    public Parameter parameter { get; set; }
    public Payload payload { get; set; }
}

public class Header
{
    public string app_id { get; set; }
    public string uid { get; set; }
}

public class Parameter
{
    public Chat chat { get; set; }
}

public class Chat
{
    public string domain { get; set; }
    public double temperature { get; set; }
    public int max_tokens { get; set; }
}

public class Payload
{
    public Message message { get; set; }
}

public class Message
{
    public List<Content> text { get; set; }
}

public class Content
{
    public string role { get; set; }
    public string content { get; set; } = "踏平坎坷成大道，推倒障碍成浮桥，熬过黑暗是黎明。";
}